package com.wind.sqlite.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


import com.google.gson.Gson;
import com.wind.httpProxyServer.bean.ProcessConfigBean;
import com.wind.httpProxyServer.manager.HttpProxyServerManager;
import com.wind.httpProxyServer.utils.SocketUtil;
import com.wind.sqlite.common.base.BaseModelPageDTO;
import com.wind.sqlite.common.exception.RRException;
import com.wind.sqlite.common.utils.PageUtils;
import com.wind.sqlite.common.utils.R;
import com.wind.sqlite.entity.ProcessConfigTEntity;
import com.wind.sqlite.entity.WhiteListTEntity;
import com.wind.sqlite.service.WhiteListTService;
import com.wind.sqlite.tools.RandomStringGenerator;
import com.wind.sqlite.tools.WhilteTools;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.wind.sqlite.service.ProcessConfigTService;







/**
 * 进程配置表
 *
 * @author bliang
 * @email 1270763655@qq.com
 * @date 2023-06-17 10:27:27
 */
@RestController
@RequestMapping("sys/processconfigt")
public class ProcessConfigTController {
    @Autowired
    private ProcessConfigTService processConfigTService;

    @Autowired
    private WhiteListTService whiteListTService;

    /**
     * 列表
     */
    @RequestMapping("/listByMap")
    //@RequiresPermissions("sqlite:processconfigt:list")
    public R listByMap(@RequestParam Map<String, Object> params){
        PageUtils page = processConfigTService.queryPage(params);

        return R.ok().put("page", page);
    }

  /**
* 列表
*/
  @RequestMapping("/listByDto")
  public R listByDto(@RequestBody BaseModelPageDTO<ProcessConfigTEntity> data){
    PageUtils page = processConfigTService.queryPage(data);
    return R.ok().put("page", page);
  }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("sqlite:processconfigt:info")
    public R info(@PathVariable("id") Long id){
		ProcessConfigTEntity processConfigT = processConfigTService.getById(id);
        WhiteListTEntity whiteListTEntity =new WhiteListTEntity();
        whiteListTEntity.setProcessId(id);
        List<WhiteListTEntity> whiteListTEntitys = whiteListTService.query(whiteListTEntity);
        if(CollectionUtils.isNotEmpty(whiteListTEntitys)){
            List<String> ips = whiteListTEntitys.stream().map(WhiteListTEntity::getIp).collect(Collectors.toList());
            processConfigT.setIps(ips);
        }
        return R.ok().put("processConfigT", processConfigT);
    }

    @RequestMapping("/init")
    public R random(){
        ProcessConfigTEntity processConfigT = new ProcessConfigTEntity();
        processConfigT.setPort(RandomStringGenerator.getFreePort());
        processConfigT.setUsername(RandomStringGenerator.generateRandomString(10));
        processConfigT.setPassword(RandomStringGenerator.generateRandomString(10));
        return R.ok().put("processConfigT", processConfigT);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("sqlite:processconfigt:save")
    public R save(@RequestBody BaseModelPageDTO<ProcessConfigTEntity> processConfigT){
        ProcessConfigTEntity data = processConfigT.getData();
        List<String> ips = data.getIps();
        //查询端口是否冲突
        ProcessConfigTEntity pocessConfigTQuery=new ProcessConfigTEntity();
        pocessConfigTQuery.setPort(data.getPort());
        ProcessConfigTEntity processConfigTEntityOne = processConfigTService.queryOne(pocessConfigTQuery);
        if(processConfigTEntityOne!=null){
            throw new RRException("端口"+data.getPort()+"已经存于数据库,请更换端口号");
        }
        boolean portOpen = SocketUtil.portIsUse(data.getPort());
        if(!portOpen){
            throw new RRException("端口"+data.getPort()+"已经占用，请更换端口号");
        }
        //保存数据库
        processConfigTService.save(data);
        if(CollectionUtils.isNotEmpty(ips)){
            Long id = data.getId();
            //先删除在插入
            WhiteListTEntity whiteListTEntityRemove =new WhiteListTEntity();
            whiteListTEntityRemove.setProcessId(id);
            whiteListTService.remove(whiteListTEntityRemove);
            List<WhiteListTEntity> whiteListTEntitys =new ArrayList<>();
            for(String ip:ips){
                WhiteListTEntity whiteListTEntity =new WhiteListTEntity();
                whiteListTEntity.setProcessId(id);
                whiteListTEntity.setIp(ip);
                whiteListTEntitys.add(whiteListTEntity);
            }
            whiteListTService.saveBatch(whiteListTEntitys);
            WhilteTools.setWhilteToCache();
        }
        //启动服务
        Gson gson = new Gson();
        ProcessConfigBean processConfigBean = gson.fromJson(gson.toJson(data), ProcessConfigBean.class);
        HttpProxyServerManager.start(processConfigBean);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("sqlite:processconfigt:update")
    public R update(@RequestBody BaseModelPageDTO<ProcessConfigTEntity> processConfigT){
        ProcessConfigTEntity data = processConfigT.getData();

        ProcessConfigTEntity oldProcessConfigTEntity = processConfigTService.getById(data.getId());
        Integer oldPort = oldProcessConfigTEntity.getPort();
        Boolean oldStatus = oldProcessConfigTEntity.getStatus();
        Integer newPort = data.getPort();
        Boolean newStatus = data.getStatus();
        processConfigTService.updateById(data);
        List<String> ips = data.getIps();
        if(CollectionUtils.isNotEmpty(ips)){
            Long id = data.getId();
            //先删除在插入
            WhiteListTEntity whiteListTEntityRemove =new WhiteListTEntity();
            whiteListTEntityRemove.setProcessId(id);
            whiteListTService.remove(whiteListTEntityRemove);
            List<WhiteListTEntity> whiteListTEntitys =new ArrayList<>();
            for(String ip:ips){
                WhiteListTEntity whiteListTEntity =new WhiteListTEntity();
                whiteListTEntity.setProcessId(id);
                whiteListTEntity.setIp(ip);
                whiteListTEntitys.add(whiteListTEntity);
            }
            whiteListTService.saveBatch(whiteListTEntitys);
            WhilteTools.setWhilteToCache();
        }

        //更换端口 关闭老端口代理服务，开启新端口服务
        //新老状态都是开启，并且端口改变
        Gson gson = new Gson();
        if(newStatus&&oldStatus) {
            if (!newPort.equals(oldPort)) {
                ProcessConfigBean oldProcessConfigBean = gson.fromJson(gson.toJson(oldProcessConfigTEntity), ProcessConfigBean.class);
                HttpProxyServerManager.close(oldProcessConfigBean);
                ProcessConfigBean newProcessConfigBean = gson.fromJson(gson.toJson(data), ProcessConfigBean.class);
                HttpProxyServerManager.start(newProcessConfigBean);
            }
            //关闭动作
        }else if(oldStatus&&!newStatus){
            ProcessConfigBean oldProcessConfigBean = gson.fromJson(gson.toJson(oldProcessConfigTEntity), ProcessConfigBean.class);
            HttpProxyServerManager.close(oldProcessConfigBean);
            //开启动作
        }else if(!oldStatus&&newStatus){
            ProcessConfigBean newProcessConfigBean = gson.fromJson(gson.toJson(data), ProcessConfigBean.class);
            HttpProxyServerManager.start(newProcessConfigBean);
        }
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    //@RequiresPermissions("sqlite:processconfigt:delete")
    public R delete(@RequestBody Long[] ids){
		for(Long id :ids){
            ProcessConfigTEntity processConfigTEntity = processConfigTService.getById(id);
            Gson gson = new Gson();
            ProcessConfigBean processConfigBean = gson.fromJson(gson.toJson(processConfigTEntity), ProcessConfigBean.class);
            HttpProxyServerManager.close(processConfigBean);
        }
        processConfigTService.removeByIds(Arrays.asList(ids));
        WhilteTools.setWhilteToCache();


        return R.ok();
    }



    public static void main(String[] args) {
        for(int i =0;i<10000;i++){
            boolean portIsUse = SocketUtil.portIsUse(i);
            if(!portIsUse){
                System.out.println(i);
            }
        }
    }
}
